import hmac
import hashlib
import os
import random
import cv2
import numpy as np
from tkinter import *
import tkinter.messagebox
from tkinter.simpledialog import askstring

def qpow(a, x, mod):
	res = 1
	while (x>0):
		if (x&1):
			res = res*a%mod
		a = a*a%mod
		x = x>>1
	return res

def miller_rabin(a, n):
	x = n-1
	while ((x&1)==0 and x>0):
		temp = qpow(a, x, n)
		if (temp!=1 and temp!=n-1):
			return False
		if (temp == n-1):
			return True
		x = x>>1
	return True

def is_prime(x):
	a = [2, 3, 5, 7, 11, 19260817]
	res = False
	for i in range(0, 6):
		if (x == a[i]):
			return True
		if (x%a[i] == 0):
			return False
		if (not miller_rabin(a[i], x)):
			return False
	return True

'''生成n位的随机大素数'''
def rand_prime(n):
	res = random.randrange(2**(n-1)+1, 2**n, 2)
	while (not is_prime(res)):
		res = res+2
	return res

'''处理函数'''


def to16(x):
	if (x.isdigit()):
		return ord(x) - ord('0')
	if (x.islower()):
		return ord(x) - ord('a') + 10
	if (x.isupper()):
		return ord(x) - ord('A') + 10
	return 0

def solve(src, hash, dst):
	img = cv2.imread(src, cv2.IMREAD_UNCHANGED)
	rows, cols, channels = img.shape
	p = 0
	for i in range(rows):
		for j in range(cols):
			mask = to16(hash[p]);
			if (++p >= len(hash)):
				p = 0
			img[i, j, 0] ^= mask & 0x07;
			img[i, j, 1] ^= (mask & 0x0e) >> 1;
			img[i, j, 2] ^= mask & 0x07;
	cv2.imwrite(dst, img, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])

'''模糊处理'''
def encode():
	data = 'a'
	while (not data.isdecimal()):
		data = askstring('请输入', '请输入一串数字')
	Hash = hmac.new(bytearray(str(key).encode('utf-8')),
					data.encode('utf-8', 'surrogateescape'),
					hashlib.sha256).hexdigest()
	'''ret = os.system("Main.exe " + Hash + " encode")
	if (ret == -3):
		tkinter.messagebox.showerror(title="错误", message= file1 + "不存在")'''
	if (not os.path.exists(file1)):
		tkinter.messagebox.showerror(title="错误", message= file1 + "不存在")
		return
	else:
		solve(file1, Hash, file3)
		tkinter.messagebox.showinfo(title="完成", message="已完成")
		print('模糊处理使用：' + data)
		cv2.imshow(file3, cv2.imread(file3))
		cv2.waitKey()

'''复原'''
def decode():
	data = 'a'
	while (not data.isdecimal()):
		data = askstring('请输入', '请输入一串数字')
	Hash = hmac.new(bytearray(str(key).encode('utf-8')),
					data.encode('utf-8', 'surrogateescape'),
					hashlib.sha256).hexdigest()
	'''ret = os.system("Main.exe " + Hash + " decode")
	if (ret == -3):
		tkinter.messagebox.showerror(title="错误", message= file3 + "不存在, 先进行模糊处理")'''
	if (not os.path.exists(file3)):
		tkinter.messagebox.showerror(title="错误", message= file3 + "不存在")
		return
	else :
		solve(file3, Hash, file2)
		tkinter.messagebox.showinfo(title="完成", message="已完成")
		print('复原使用：' + data)
		cv2.imshow(file2, cv2.imread(file2))
		cv2.waitKey()

def equal():
	if (not os.path.exists(file1)):
		tkinter.messagebox.showerror(title="错误", message= file1 + "不存在")
		return
	if (not os.path.exists(file2)):
		tkinter.messagebox.showerror(title="错误", message= file2 + "不存在")
		return

	img1 = cv2.imread(file1)
	img2 = cv2.imread(file2)
	difference = cv2.subtract(img1, img2)
	result = not np.any(difference)

	if result is True:
		tkinter.messagebox.showinfo(title="比较", message="两张图片一样")
	else:
		tkinter.messagebox.showinfo(title="比较", message="两张图片不一样")

if __name__ == '__main__':
	#os.system("cmake --build ./build")
	file1 = "original picture.png"
	file2 = "decoded picture.png"
	file3 = "encoded picture.png"
	#key = random.randrange(2, rand_prime(64))
	key = 14064262489901834033
	root = Tk()
	root.title('Project 2')
	root.geometry('1024x768')
	if (os.path.exists(file1)):
		img = tkinter.PhotoImage(file=file1)
		lb1 = tkinter.Label(root, text=file1, font=('',16))
		lb1.place(relx=0.35, rely=0.0, relwidth=0.3, relheight=0.1)
		label = tkinter.Label(root, image=img)
		label.place(relx=0.2, rely=0.1, relwidth=0.6, relheight=0.6)

	bt1 = Button(root, bg='#d3fbfb', text = '模糊处理', command=encode)
	bt1.place(relx=0.15, rely=0.8, relwidth=0.1, relheight=0.05)
	bt2 = Button(root, bg='#d3fbfb', text='复原处理', command=decode)
	bt2.place(relx=0.35, rely=0.8, relwidth=0.1, relheight=0.05)
	bt3 = Button(root, bg='#d3fbfb', text='比较', command=equal)
	bt3.place(relx=0.55, rely=0.8, relwidth=0.1, relheight=0.05)
	bt4 = Button(root, bg='#d3fbfb', text='退出', command=exit)
	bt4.place(relx=0.75, rely=0.8, relwidth=0.1, relheight=0.05)
	root.mainloop()